package com.example.forum.controller;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.forum.MyQuery;
import com.example.forum.commons.authrization.TokenManager;
import com.example.forum.commons.tools.StringUtil;
import com.example.forum.commons.tools.Transfer.DataTransfer;
import com.example.forum.entity.TMenus;
import com.example.forum.entity.TPermissions;
import com.example.forum.entity.TRolepermission;
import com.example.forum.entity.TRoles;
import com.example.forum.service.ITMenusService;
import com.example.forum.service.ITPermissionsService;
import com.example.forum.service.ITRolepermissionService;
import com.example.forum.service.ITRolesService;
import com.example.forum.vo.JsonResult;
import com.example.forum.vo.RoleModel;
import com.example.forum.vo.TreeNode;
import com.example.forum.vo.ValueAndLabelModel;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import net.logstash.logback.encoder.org.apache.commons.lang.ArrayUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author why
 * @since 2019-10-30
 */


@RestController
@Api(tags = "角色控制层")
@RequestMapping("/Role")
public class TRolesController extends BaseController {

    private static final Logger LOGGER = LoggerFactory.getLogger(TRolesController.class);

    @Autowired
    private ITRolesService roleService;

    @Autowired
    private ITPermissionsService permissionsService;
    @Autowired
    private ITRolepermissionService rolePermissionService;

    @Autowired
    private ITMenusService menuService;

    @Autowired
    DataTransfer dataTransfer;

    @Autowired
    private TokenManager tokenManager;

    @ApiOperation(value = "新增角色")
    @RequestMapping(value = "/create", method = {RequestMethod.POST})
    public JsonResult create(
            @Valid @RequestBody @ApiParam(name = "角色", value = "传入json格式", required = true) RoleModel rolemodel) {
        var role = roleService.getOne(new QueryWrapper<TRoles>().eq("name", rolemodel.getName()));
        if (role != null)
            return new JsonResult(HttpStatus.BAD_REQUEST, "该角色已存在 ", null);

        TRoles rolet = new TRoles();
        rolet.setName(rolemodel.getName());
        rolet.setDescription(rolemodel.getDescription());
        roleService.save(rolet);

        var roleDto = roleService.getOne(new QueryWrapper<TRoles>().eq("name", rolemodel.getName()));

        if (rolemodel.getPermissions() != null && rolemodel.getDescription().length() > 0) {
            for (String permisId : rolemodel.getPermissions()) {
                TRolepermission rpd = new TRolepermission();
                rpd.setRoleid(roleDto.getId());
                rpd.setPermissionid(permisId);
                rolePermissionService.save(rpd);
            }
        }
        return new JsonResult(HttpStatus.OK, "新增成功 ", roleDto.getId());
    }


    @ApiOperation(value = "删除角色")
    @RequestMapping(value = "/delete", method = {RequestMethod.POST})
    public JsonResult delete(String roleId) {
        var role = roleService.getById(roleId);
        if (role == null) {
            return new JsonResult(HttpStatus.NOT_FOUND, "该角色不存在", null);
        } else {
            role.setIsdeleted(true);
            role.setDeleteruserid(currentUserId());
            roleService.updateById(role);
            return new JsonResult(HttpStatus.OK, "删除成功", null);
        }
    }


    @ApiOperation(value = "根据Id获取Role")
    @RequestMapping(value = "/getInfo", method = {RequestMethod.GET})
    public JsonResult getInfo(String roleId) {
        var roleDto = roleService.getById(roleId);
        return new JsonResult(HttpStatus.OK, "成功", roleDto);
    }


    @ApiOperation(value = "获取全部的角色")
    @RequestMapping(value = "/getRoleAll", method = {RequestMethod.GET})
    public JsonResult getRoleAll() {
        var list = roleService.list();
        return new JsonResult(HttpStatus.OK, "成功", list);
    }


    @ApiOperation(value = "根据过滤条件查询分页")
    @RequestMapping(value = "/getList", method = {RequestMethod.GET})
    public JsonResult getList(String name, Integer pageIndex, Integer pageSize) {
        Page<TRoles> page = new Page();
        page.setCurrent(pageIndex);
        if (pageSize != null)
            page.setSize(pageSize);
        var list = roleService.page(page,
                new QueryWrapper<TRoles>().eq(StringUtil.isNotEmpty(name), "name", name).eq("isdeleted", 0)
        );
        return new JsonResult(HttpStatus.OK, "成功", list);
    }


    @ApiOperation(value = "更新角色信息")
    @RequestMapping(value = "/update", method = {RequestMethod.POST})
    public JsonResult update(
            @Valid @RequestBody @ApiParam(name = "角色对象", value = "传入json格式", required = true) RoleModel rolemodel) {
        if (StringUtil.isEmpty(rolemodel.getRoleId())) {
            return new JsonResult(HttpStatus.BAD_REQUEST, "该角色Id不能为空", null);
        }
        var roledto = roleService.getById(rolemodel.getRoleId());
        if (roledto == null) {
            return new JsonResult(HttpStatus.NOT_FOUND, "不存在", null);
        } else {
            roledto.setName(rolemodel.getName());
            roledto.setDescription(rolemodel.getDescription());
            if (rolemodel.getPermissions() != null && rolemodel.getPermissions().length > 0) {
                String[] permissions = rolePermissionService.getPermissionsByRoleId(rolemodel.getRoleId());
                for (String permis : rolemodel.getPermissions()) {
                    if (!ArrayUtils.contains(permissions, permis)) {
                        TRolepermission urd = new TRolepermission();
                        urd.setRoleid(rolemodel.getRoleId());
                        urd.setPermissionid(permis);
                        rolePermissionService.save(urd);
                    }
                }
            }
            roleService.updateById(roledto);
            return new JsonResult(HttpStatus.OK, "更新成功", null);
        }
    }

    @ApiOperation(value = "更新普通权限信息")
    @RequestMapping(value = "/updateOtherPermissions", method = {RequestMethod.POST})
    public JsonResult updateOtherPermissions(
            @RequestBody @ApiParam(name = "角色对象", value = "传入json格式", required = true) RoleModel rolemodel) {
        LOGGER.info("更新普通权限信息");

        if (StringUtil.isEmpty(rolemodel.getRoleId())) {
            return new JsonResult(HttpStatus.BAD_REQUEST, "该角色Id不能为空", null);
        }

        var roledto = roleService.getById(rolemodel.getRoleId());
        if (roledto == null) {
            return new JsonResult(HttpStatus.NOT_FOUND, "不存在", null);
        } else {
            if (rolemodel.getPermissions() != null && rolemodel.getPermissions().length > 0) {
                String[] permissions = rolePermissionService.getPermissionsByRoleId(rolemodel.getRoleId());

                for (String permis : rolemodel.getPermissions()) {
                    if (!ArrayUtils.contains(permissions, permis)) {
                        TRolepermission urd = new TRolepermission();
                        urd.setRoleid(rolemodel.getRoleId());
                        urd.setPermissionid(permis);
                        rolePermissionService.save(urd);
                    }
                }
            }
            return new JsonResult(HttpStatus.OK, "更新成功", null);
        }
    }


    @ApiOperation(value = "获取选中的权限")
    @RequestMapping(value = "/getCheckedPermissionIds", method = {RequestMethod.GET})
    public JsonResult getCheckedPermissionIds(String roleId) {
        String[] noparentPermissions = menuService.findPermissionsNotParentByRoleId(roleId);
        return new JsonResult(HttpStatus.OK, "成功", noparentPermissions);
    }


    @ApiOperation(value = "更新菜单权限")
    @RequestMapping(value = "/CheckTree", method = {RequestMethod.POST})
    public JsonResult CheckTree(String roleid, String checkednodes) {

        //先删除旧的权限
        roleService.deleteMenuPermissionsByRoleId(roleid);

        //再添加新的权限
        List<TRolepermission> newList = new ArrayList<>();
        if (StringUtil.isNotEmpty(checkednodes)) {
            String[] permission_arr = checkednodes.split(",");
            for (String s : permission_arr) {
                TRolepermission model = new TRolepermission();
                model.setRoleid(roleid);
                model.setPermissionid(s);
                newList.add(model);
            }
            rolePermissionService.saveBatch(newList);
        }

//        String[] checkpemissionIds = checkednodes.split(",");
//        String[] oldCheckedMenuPermissions = roleService.getMenuCheckedPermissions(roleid);
//        for (String permis : checkpemissionIds) {
//            if (!Arrays.asList(oldCheckedMenuPermissions).contains(permis)) {
//                TRolepermission rpd = new TRolepermission();
//                rpd.setTRoleId(roleid);
//                rpd.setPermissionId(permis);
//                rolePermissionService.save(rpd);
//            }
//        }
        return new JsonResult(HttpStatus.OK, "操作成功", null);
    }


    @ApiOperation(value = "加载菜单权限树")
    @RequestMapping(value = "/loadMenuTree", method = {RequestMethod.GET})
    public JsonResult loadMenuTree() {
        String currentUserId = currentUserId();
        var treeNodes = new ArrayList<TreeNode>();
        var treeNodesResults = new ArrayList<TreeNode>();
        var resultPermission = roleService.GetAllPermissionsForTree();
        var AllresultP = menuService.list(new MyQuery<>());
        var resultMenu = AllresultP.stream().filter(m -> m.getParentid() == null)
                .collect(Collectors.toList());
        var permissIDs = permissionsService.GetPermissionIdByUserId(currentUserId);

        if (resultPermission != null && resultPermission.size() > 0) {
            resultPermission.forEach(temp -> {
                Map map = (Map) temp;
                var treeNode = new TreeNode();
                treeNode.setShowEdit(false);
                treeNode.setShowRemove(false);
                treeNode.setId(map.get("ID").toString());
                treeNode.setParentid(map.get("PARENTID") == null ? "0" : map.get("PARENTID").toString());

                if (map.get("PERMISSIONID") == null || map.get("PERMISSIONID").toString() == "") {
                    return;
                }
                treeNode.setPermissionId(map.get("PERMISSIONID").toString());

                if (ArrayUtils.contains(permissIDs, map.get("PERMISSIONID").toString())) {
                    treeNode.setCheck("true");
                } else {
                    treeNode.setCheck("false");
                }
                treeNode.setName(map.get("NAME").toString());
                treeNode.setSort(Integer.parseInt(map.get("ORDERIN").toString()));
                treeNode.setIsParent(Integer.parseInt(map.get("CHILDRENNUMBER").toString()) > 0 ? "true" : "false");
                treeNodes.add(treeNode);
            });
        }

        if (treeNodes.size() > 0 && resultMenu != null && resultMenu.size() > 0) {
            resultMenu.forEach(temp -> {
                var treeNode = new TreeNode();
                treeNode.setShowEdit(false);
                treeNode.setShowRemove(false);
                treeNode.setId(temp.getId());
                treeNode.setParentid(temp.getParentid());
                treeNode.setName(temp.getName());
                treeNode.setSort(Integer.parseInt(temp.getOrderin().toString()));
                treeNode.setIsParent("true");
                var children = treeNodes.stream().filter((m) -> m.getId().equals(temp.getId())).findAny().orElse(null);;
                if (children != null) {
                    treeNode.setPermissionId(children.getPermissionId());
                    treeNode.setCheck(children.getCheck());
                } else {
                    return;
                }
                treeNode.setSort(temp.getOrderin());
                CreateTreeView(treeNodes, treeNode);
                treeNodesResults.add(treeNode);
            });
        }
        return new JsonResult(HttpStatus.OK, "加载成功", treeNodesResults);
    }


    private void CreateTreeView(List<TreeNode> TreeNodes, TreeNode treeModel) {
        List<TreeNode> children = TreeNodes.stream()
                .filter((m) -> m.getParentid().equals(treeModel.getId()))
                .sorted(Comparator.comparing(TreeNode::getSort)).collect(Collectors.toList());
        if (children.size() == 0) {
            treeModel.children = children;
        }
        treeModel.children = new ArrayList<TreeNode>();

        children.forEach(temp -> {
            treeModel.children.add(temp);
            CreateTreeView(TreeNodes, temp);
        });

    }


    @ApiOperation(value = "根据角色id获取菜单权限")
    @RequestMapping(value = "/getPermissionByRoleId", method = {RequestMethod.GET})
    public JsonResult getPermissionByRoleId(String roleId) {
        //角色所有权限
        var ids = roleService.getMenuCheckedPermissions(roleId);
        //获取主菜单
        var menuBase = menuService.list(new MyQuery<>()).stream().filter(m -> m.getParentid() == null).collect(Collectors.toList());
        List<String> menuBaseList = new ArrayList<>();
        menuBase.forEach(m -> {
            menuBaseList.add(m.getPermissiontarget());
        });

        //获取主菜单所有权限
        var parnetPermissionListIDs = permissionsService.list(new MyQuery<>()).stream().filter(m -> menuBaseList.contains(m.getTargetname())).map(m -> m.getId()).collect(Collectors.toList());
        //排除含主菜单
        List<String> list = new ArrayList<>(Arrays.asList(ids));
        list = list.stream().filter(m -> !parnetPermissionListIDs.contains(m)).collect(Collectors.toList());

        return new JsonResult(HttpStatus.OK, "加载成功", list);
    }


    //todo 普通权限...

    @ApiOperation(value = "加载普通权限")
    @RequestMapping(value = "/LoadNormalTree", method = {RequestMethod.GET})
    public JsonResult LoadNormalTree() {
        var result = new ArrayList<ValueAndLabelModel>();
        var list = permissionsService.list().stream().filter(m -> m.getPermissiontype().equals(2)&&m.getIsdeleted().equals(false))
                .sorted(Comparator.comparing(TPermissions::getTargetname).reversed()).collect(Collectors.toList());
        Map<String, List<TPermissions>> listgroup = list.stream()
                .collect(Collectors.groupingBy(TPermissions::getTargetname));
        Integer i = 0;
        for (Map.Entry<String, List<TPermissions>> entry : listgroup.entrySet()) {
            String key = entry.getKey();
            List<TPermissions> entryList = entry.getValue();
            var model = new ValueAndLabelModel(i.toString(), key == null || key.isEmpty() ? "其他" : key, null);
            var childrenlist = new ArrayList<ValueAndLabelModel>();

            entryList.forEach(m -> {
                var cmodel = new ValueAndLabelModel(m.getId(), m.getDisplayname(), null);
                childrenlist.add(cmodel);
            });
            i++;
            model.setChildren(childrenlist);
            result.add(model);
        }
        return new JsonResult(HttpStatus.OK, "加载成功", result);
    }


    @ApiOperation(value = "根据角色id获取普通权限")
    @RequestMapping(value = "/getNormalPermissionByRoleId", method = {RequestMethod.GET})
    public JsonResult getNormalPermissionByRoleId(String roleId) {
        var ids = roleService.getNormalCheckedPermissions(roleId);
        return new JsonResult(HttpStatus.OK, "加载成功", ids);
    }


    @ApiOperation(value = "更新普通权限")
    @RequestMapping(value = "/updateNormalPermissions", method = {RequestMethod.POST})
    public JsonResult updateNormalPermissions(String roleId, String permissions) {
        //先删除旧的权限
        roleService.deleteNormalPermissionsByRoleId(roleId);

        //再添加新的权限
        List<TRolepermission> newList = new ArrayList<>();
        if (StringUtil.isNotEmpty(permissions)) {
            String[] permission_arr = permissions.split(",");
            for (String s : permission_arr) {
                TRolepermission model = new TRolepermission();
                model.setRoleid(roleId);
                model.setPermissionid(s);
                newList.add(model);
            }
            rolePermissionService.saveBatch(newList);
        }
        return new JsonResult(HttpStatus.OK, "成功", null);
    }
}

